;; -*- mode: Lisp; tab-width: 4; -*-

;; this file illustrates main concepts to OALI language.


;; #1. Region inference, #2.1. Type inference, #2.2. Type injection.

(type text const-char-ptr)

;; type of argument text is inferenced (injected) by it's name -
;;           and it becomes const-char-ptr.
;; type of filename is inferenced from the usage point - see call to fopen
(func write-text (filename text)
	  (let ((file (fopen filename "wb")))
		(fwrite text (sizeof-char-in text) (length text) file)))

;; | |
;; | |
;;  V

#|

void write_text(const char * filename, const char * text) {
    FILE * file = fopen(filename, "wb");
    if (file != NULL) {
        fwrite(text, 1, strlen(text), file);

        // end of region is inferenced for file
        fclose(file);
    }
}

|#


;; #3. Aspects. (Highly coupled with markers, problem domain integration, etc)

(aspect :oali.support.commandline
		(import :oali.lang.c.stdio)
		
		(func main (argc argv)
			  (args (argc int) (argv const-char-pp))
			  (returns int)

			  (let ((result))
				(marker :parse-command-line (argc argv)
						(marker :run-app (result))
						result)))

		(aspect :standard-arguments-parser
				
				(in-marker :parse-command-line (argc argv)
						   (dotimes (i argc)
							 (if (eq (strcmp (elt argv i) "--help") 0)
								 (fputs "Help message goes here" stdout)))))


		) ;; aspect: command line app

;; #4. Problem domain integration (see description below)

(module
 :oali.domain.streams

 (type file)
 (is opened-file file (traits :pointer :not-null))

 (func fopen (file-name open-mode)
	   (returns :success opened-file :failure null))

 (func fread (buffer size count opened-file)
	   (returns read-count))

 (func fwrite (read-only-buffer size count opened-file)
	   (returns written-count (traits (equals-to count))))

 (func fclose (opened-file)
	   (traits (releases opened-file)))

 (scenario write-to-file ((provider context-provider) file-name)
		   (let ((file (fopen file-name "rb")))
			 (perform-action :context-provider provider
							 :action (fwrite (get-byte-buffer provider)
											 1
											 (get-size-of-byte-buffer provider)
											 file)
							 :repeatable t)
			 (fclose file)))

 (scenario read-file-to-buffer (file-name writeable-buffer buffer-reader)
		   (let (bytes-read (opened-file (fopen file-name "rb")))
			 (infinite-loop
			  (set bytes-read (fread writeable-buffer 1 (size-of writeable-buffer)))
			  (if (<= bytes-read 0)
				  (break))
			  (buffer-reader writeable-buffer bytes-read))))

 ;; alt variant of the scenario given above
 (scenario read-from-binary-file ((provider context-provider) file-name)
		   (let ((file (fopen file-name "rb")))
			 (pluggable-action :context provider :iterable t
							   :action ())))

 
 t)

#|

Ontology operates on:

- Instances (main, low-level components, e.g. physical objects like planets, peoples or abstract ones, like numbers, words).

- Concepts (or classes) - abstract groups, collections or sets of objects, that includes other concepts and/or instances.
Sample concept: concept peoples, man is embedded concept.
Concept - personnel, instance: employee.

- Attributes. Ontology objects might have attributes. Each attribute have, at least, name and value. Used to store object-specific information that is bound to the object.
Sample: The Ford Explorer has the following attributes:
* Name: Ford Explorer
* Number-of-Doors: 4
* Engine: [4.0L, 4.6L]
* Gearbox: 6-speed
If attributes are not defined, the ontology would require Taxonomy or Controlled Dictionary to be defined.

- Relations. Attributes' important role is to define relationships between the objects of ontology.
Sample: Let Ford Bronco is a successor model of the Ford Explorer. Then relation ship between Ford Bronco and Ford Explorer can be defined as:
* isSuccessorOf with value "Explorer" for the "Bronco" object.



|#